/*! ******************************************************************************
 *
 * Pentaho Data Integration
 *
 * Copyright (C) 2002-2017 by Hitachi Vantara : http://www.pentaho.com
 *
 *******************************************************************************
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with
 * the License. You may obtain a copy of the License at
 *
 *    http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 ******************************************************************************/

package org.pentaho.di.core.logging;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;

import org.pentaho.di.core.metrics.MetricsSnapshotType;
import org.pentaho.di.i18n.BaseMessages;

public class Metrics implements MetricsInterface  {

  private static Class<?> PKG = Metrics.class; // for i18n purposes, needed by Translator2!!
  
  // Database
  //
  public static Metrics METRIC_DATABASE_CONNECT_START = new Metrics(
    MetricsSnapshotType.START, "METRIC_DATABASE_CONNECT",BaseMessages.getString( PKG, "Metric.Database.Connect.Start" ));
  public static Metrics METRIC_DATABASE_CONNECT_STOP = new Metrics(
    MetricsSnapshotType.STOP, "METRIC_DATABASE_CONNECT",BaseMessages.getString( PKG, "Metric.Database.Connect.Stop"));
  public static Metrics METRIC_DATABASE_PREPARE_SQL_START = new Metrics(
    MetricsSnapshotType.START, "METRIC_DATABASE_PREPARE_SQL",BaseMessages.getString( PKG, "Metric.Database.Prepare.Sql.Start" ));
  public static Metrics METRIC_DATABASE_PREPARE_SQL_STOP = new Metrics(
    MetricsSnapshotType.STOP, "METRIC_DATABASE_PREPARE_SQL", BaseMessages.getString( PKG,"Metric.Database.Prepare.Sql.Stop" ));
  public static Metrics METRIC_DATABASE_CREATE_SQL_START = new Metrics(
    MetricsSnapshotType.START, "METRIC_DATABASE_CREATE_SQL",BaseMessages.getString( PKG, "Metric.Database.Create.Sql.Start" ));
  public static Metrics METRIC_DATABASE_CREATE_SQL_STOP = new Metrics(
    MetricsSnapshotType.STOP, "METRIC_DATABASE_CREATE_SQL",BaseMessages.getString( PKG,"Metric.Database.Create.Sql.Stop" ));
  public static Metrics METRIC_DATABASE_SQL_VALUES_START = new Metrics(
    MetricsSnapshotType.START, "METRIC_DATABASE_SQL_VALUES",BaseMessages.getString( PKG, "Metric.Database.Sql.Values.Start" ));
  public static Metrics METRIC_DATABASE_SQL_VALUES_STOP = new Metrics(
    MetricsSnapshotType.STOP, "METRIC_DATABASE_SQL_VALUES", BaseMessages.getString( PKG,"Metric.Database.Sql.Values.Stop" ));
  public static Metrics METRIC_DATABASE_EXECUTE_SQL_START = new Metrics(
    MetricsSnapshotType.START, "METRIC_DATABASE_EXECUTE_SQL",BaseMessages.getString( PKG, "Metric.Database.Execute.Sql.Start" ));
  public static Metrics METRIC_DATABASE_EXECUTE_SQL_STOP = new Metrics(
    MetricsSnapshotType.STOP, "METRIC_DATABASE_EXECUTE_SQL",BaseMessages.getString( PKG, "Metric.Database.Execute.Sql.Stop" ));
  public static Metrics METRIC_DATABASE_OPEN_QUERY_START = new Metrics(
    MetricsSnapshotType.START, "METRIC_DATABASE_OPEN_QUERY",BaseMessages.getString( PKG, "Metric.Database.Open.Query.Start" ));
  public static Metrics METRIC_DATABASE_OPEN_QUERY_STOP = new Metrics(
    MetricsSnapshotType.STOP, "METRIC_DATABASE_OPEN_QUERY", BaseMessages.getString( PKG,"Metric.Database.Open.Query.Stop" ));
  public static Metrics METRIC_DATABASE_GET_ROW_META_START = new Metrics(
    MetricsSnapshotType.START, "METRIC_DATABASE_GET_ROW_META",BaseMessages.getString( PKG, "Metric.Database.Get.Row.Meta.Start" ));
  public static Metrics METRIC_DATABASE_GET_ROW_META_STOP = new Metrics(
    MetricsSnapshotType.STOP, "METRIC_DATABASE_GET_ROW_META", BaseMessages.getString( PKG,"Metric.Database.Get.Row.Meta.Stop" ));
  public static Metrics METRIC_DATABASE_SET_LOOKUP_START = new Metrics(
    MetricsSnapshotType.START, "METRIC_DATABASE_SET_LOOKUP", BaseMessages.getString( PKG,"Metric.Database.Set.Lookup.Start" ));
  public static Metrics METRIC_DATABASE_SET_LOOKUP_STOP = new Metrics(
    MetricsSnapshotType.STOP, "METRIC_DATABASE_SET_LOOKUP", BaseMessages.getString( PKG,"Metric.Database.Set.Lookup.Stop" ));
  public static Metrics METRIC_DATABASE_PREPARE_UPDATE_START = new Metrics(
    MetricsSnapshotType.START, "METRIC_DATABASE_PREPARE_UPDATE",BaseMessages.getString( PKG, "Metric.Database.Prepare.Update.Start" ));
  public static Metrics METRIC_DATABASE_PREPARE_UPDATE_STOP = new Metrics(
    MetricsSnapshotType.STOP, "METRIC_DATABASE_PREPARE_UPDATE",BaseMessages.getString( PKG, "Metric.Database.Prepare.Update.Stop" ));
  public static Metrics METRIC_DATABASE_PREPARE_DELETE_START = new Metrics(
    MetricsSnapshotType.START, "METRIC_DATABASE_PREPARE_DELETE",BaseMessages.getString( PKG, "Metric.Database.Prepare.Delete.Start" ));
  public static Metrics METRIC_DATABASE_PREPARE_DELETE_STOP = new Metrics(
    MetricsSnapshotType.STOP, "METRIC_DATABASE_PREPARE_DELETE", BaseMessages.getString( PKG, "Metric.Database.Prepare.Delete.Stop" ));
  public static Metrics METRIC_DATABASE_PREPARE_DBPROC_START = new Metrics(
    MetricsSnapshotType.START, "METRIC_DATABASE_PREPARE_DBPROC",BaseMessages.getString( PKG, "Metric.Database.Prepare.Dbproc.Start" ));
  public static Metrics METRIC_DATABASE_PREPARE_DBPROC_STOP = new Metrics(
    MetricsSnapshotType.STOP, "METRIC_DATABASE_PREPARE_DBPROC",BaseMessages.getString( PKG, "Metric.Database.Prepare.Dbproc.Stop" ));
  public static Metrics METRIC_DATABASE_GET_LOOKUP_START = new Metrics(
    MetricsSnapshotType.START, "METRIC_DATABASE_GET_LOOKUP",BaseMessages.getString( PKG, "Metric.Database.Get.Lookup.Start" ));
  public static Metrics METRIC_DATABASE_GET_LOOKUP_STOP = new Metrics(
    MetricsSnapshotType.STOP, "METRIC_DATABASE_GET_LOOKUP",BaseMessages.getString( PKG, "Metric.Database.Get.Lookup.Stop" ));
  public static Metrics METRIC_DATABASE_GET_DBMETA_START = new Metrics(
    MetricsSnapshotType.START, "METRIC_DATABASE_GET_DBMETA",BaseMessages.getString( PKG, "Metric.Database.Get.Dbmeta.Start" ));
  public static Metrics METRIC_DATABASE_GET_DBMETA_STOP = new Metrics(
    MetricsSnapshotType.STOP, "METRIC_DATABASE_GET_DBMETA",BaseMessages.getString( PKG, "Metric.Database.Get.Dbmeta.Stop" ));

  public static Metrics METRIC_DATABASE_GET_ROW_COUNT = new Metrics(
    MetricsSnapshotType.COUNT, "METRIC_DATABASE_GET_ROW_COUNT", BaseMessages.getString( PKG, "Metric.Database.Get.Row.Count" ));
  public static Metrics METRIC_DATABASE_GET_ROW_SUM_TIME = new Metrics(
    MetricsSnapshotType.SUM, "METRIC_DATABASE_GET_ROW_SUM_TIME",BaseMessages.getString( PKG, "Metric.Database.Get.Row.Sum.Time" ));
  public static Metrics METRIC_DATABASE_GET_ROW_MIN_TIME = new Metrics(
    MetricsSnapshotType.MIN, "METRIC_DATABASE_GET_ROW_MIN_TIME",BaseMessages.getString( PKG, "Metric.Database.Get.Row.Min.Time" ));
  public static Metrics METRIC_DATABASE_GET_ROW_MAX_TIME = new Metrics(
    MetricsSnapshotType.MAX, "METRIC_DATABASE_GET_ROW_MAX_TIME",BaseMessages.getString( PKG, "Metric.Database.Get.Row.Max.Time" ));

  // Plugin registry...
  //
  public static Metrics METRIC_PLUGIN_REGISTRY_REGISTER_EXTENSIONS_START = new Metrics(
    MetricsSnapshotType.START, "METRIC_PLUGIN_REGISTRY_REGISTER_EXTENSIONS",BaseMessages.getString( PKG, "Metric.Plugin.Registry.Register.Extensions.Start" ));
  public static Metrics METRIC_PLUGIN_REGISTRY_REGISTER_EXTENSIONS_STOP = new Metrics(
    MetricsSnapshotType.STOP, "METRIC_PLUGIN_REGISTRY_REGISTER_EXTENSIONS",BaseMessages.getString( PKG, "Metric.Plugin.Registry.Register.Extensions.Stop" ));
  public static Metrics METRIC_PLUGIN_REGISTRY_REGISTER_EXTENSION_START = new Metrics(
    MetricsSnapshotType.START, "METRIC_PLUGIN_REGISTRY_REGISTER_EXTENSION",BaseMessages.getString( PKG, "Metric.Plugin.Registry.Register.Extension.Start" ));
  public static Metrics METRIC_PLUGIN_REGISTRY_REGISTER_EXTENSION_STOP = new Metrics(
    MetricsSnapshotType.STOP, "METRIC_PLUGIN_REGISTRY_REGISTER_EXTENSION",BaseMessages.getString( PKG, "Metric.Plugin.Registry.Register.Extension.Stop" ));
  public static Metrics METRIC_PLUGIN_REGISTRY_PLUGIN_REGISTRATION_START = new Metrics(
    MetricsSnapshotType.START, "METRIC_PLUGIN_REGISTRY_PLUGIN_REGISTRATION",BaseMessages.getString( PKG, "Metric.Plugin.Registry.Plugin.Registration.Start" ));
  public static Metrics METRIC_PLUGIN_REGISTRY_PLUGIN_REGISTRATION_STOP = new Metrics(
    MetricsSnapshotType.STOP, "METRIC_PLUGIN_REGISTRY_PLUGIN_REGISTRATION", BaseMessages.getString( PKG,"Metric.Plugin.Registry.Plugin.Registration.Stop" ));
  public static Metrics METRIC_PLUGIN_REGISTRY_PLUGIN_TYPE_REGISTRATION_START = new Metrics(
    MetricsSnapshotType.START, "METRIC_PLUGIN_REGISTRY_PLUGIN_TYPE_REGISTRATION",
    BaseMessages.getString( PKG, "Metric.Plugin.Registry.Plugin.Type.Registration.Start" ));
  public static Metrics METRIC_PLUGIN_REGISTRY_PLUGIN_TYPE_REGISTRATION_STOP = new Metrics(
    MetricsSnapshotType.STOP, "METRIC_PLUGIN_REGISTRY_PLUGIN_TYPE_REGISTRATION",
    BaseMessages.getString( PKG, "Metric.Plugin.Registry.Plugin.Type.Registration.Stop" ));

  // Transformation
  //
  public static Metrics METRIC_TRANSFORMATION_EXECUTION_START = new Metrics(
    MetricsSnapshotType.START, "METRIC_TRANSFORMATION_EXECUTION", BaseMessages.getString( PKG,"Metric.Transformation.Execution.Start" ));
  public static Metrics METRIC_TRANSFORMATION_EXECUTION_STOP = new Metrics(
    MetricsSnapshotType.STOP, "METRIC_TRANSFORMATION_EXECUTION", BaseMessages.getString( PKG,"Metric.Transformation.Execution.Stop" ));
  public static Metrics METRIC_TRANSFORMATION_INIT_START = new Metrics(
    MetricsSnapshotType.START, "METRIC_TRANSFORMATION_INIT", BaseMessages.getString( PKG,"Metric.Transformation.Init.Start" ));
  public static Metrics METRIC_TRANSFORMATION_INIT_STOP = new Metrics(
    MetricsSnapshotType.STOP, "METRIC_TRANSFORMATION_INIT", BaseMessages.getString( PKG,"Metric.Transformation.Init.Stop" ));
  public static Metrics METRIC_STEP_EXECUTION_START = new Metrics(
    MetricsSnapshotType.START, "METRIC_STEP_EXECUTION", BaseMessages.getString( PKG,"Metric.Step.Execution.Start" ));
  public static Metrics METRIC_STEP_EXECUTION_STOP = new Metrics(
    MetricsSnapshotType.STOP, "METRIC_STEP_EXECUTION",BaseMessages.getString( PKG, "Metric.Step.Execution.Stop" ));
  public static Metrics METRIC_STEP_INIT_START = new Metrics(
    MetricsSnapshotType.START, "METRIC_STEP_INIT", BaseMessages.getString( PKG, "Metric.Step.Init.Start" ));
  public static Metrics METRIC_STEP_INIT_STOP = new Metrics(
    MetricsSnapshotType.STOP, "METRIC_STEP_INIT", BaseMessages.getString( PKG, "Metric.Step.Init.Stop" ));

  // Logging back-end
  //
  public static Metrics METRIC_CENTRAL_LOG_STORE_TIMEOUT_CLEAN_TIME = new Metrics(
    MetricsSnapshotType.SUM, "METRIC_CENTRAL_LOG_STORE_TIMEOUT_CLEAN_TIME",
    BaseMessages.getString( PKG, "Metric.Central.Log.Store.Timeout.Clean.Time" ));
  public static Metrics METRIC_CENTRAL_LOG_STORE_TIMEOUT_CLEAN_COUNT = new Metrics(
    MetricsSnapshotType.COUNT, "METRIC_CENTRAL_LOG_STORE_TIMEOUT_CLEAN_COUNT",
    BaseMessages.getString( PKG, "Metric.Central.Log.Store.Timeout.Clean.Count" ));
  public static Metrics METRIC_LOGGING_REGISTRY_CLEAN_TIME = new Metrics(
    MetricsSnapshotType.SUM, "METRIC_LOGGING_REGISTRY_CLEAN_TIME",
    BaseMessages.getString( PKG,"Metric.Logging.Registry.Clean.Time" ));
  public static Metrics METRIC_LOGGING_REGISTRY_CLEAN_COUNT = new Metrics(
    MetricsSnapshotType.COUNT, "METRIC_LOGGING_REGISTRY_CLEAN_COUNT",
    BaseMessages.getString( PKG, "Metric.Logging.Registry.Clean.Count" ));
  public static Metrics METRIC_LOGGING_REGISTRY_GET_CHILDREN_TIME = new Metrics(
    MetricsSnapshotType.SUM, "METRIC_LOGGING_REGISTRY_GET_CHILDREN_TIME",
    BaseMessages.getString( PKG, "Metric.Logging.Registry.Get.Children.Time" ));
  public static Metrics METRIC_LOGGING_REGISTRY_GET_CHILDREN_COUNT = new Metrics(
    MetricsSnapshotType.COUNT, "METRIC_LOGGING_REGISTRY_GET_CHILDREN_COUNT",
    BaseMessages.getString( PKG,"Metric.Logging.Registry.Get.Children.Count" ));

  // Job
  //
  public static Metrics METRIC_JOB_START = new Metrics(
    MetricsSnapshotType.START, "METRIC_JOB_EXECUTION",BaseMessages.getString( PKG, "Metric.Job.Start" ));
  public static Metrics METRIC_JOB_STOP = new Metrics(
    MetricsSnapshotType.STOP, "METRIC_JOB_EXECUTION",BaseMessages.getString( PKG, "Metric.Job.Stop" ));
  public static Metrics METRIC_JOBENTRY_START = new Metrics(
    MetricsSnapshotType.START, "METRIC_JOBENTRY_EXECUTION",BaseMessages.getString( PKG, "Metric.Jobentry.Start" ));
  public static Metrics METRIC_JOBENTRY_STOP = new Metrics(
    MetricsSnapshotType.STOP, "METRIC_JOBENTRY_EXECUTION", BaseMessages.getString( PKG,"Metric.Jobentry.Stop" ));

  private String code;
  private String description;
  private MetricsSnapshotType type;

  public Metrics( MetricsSnapshotType type, String code, String description ) {
    this.type = type;
    this.code = code;
    this.description = description;
  }

  @Override
  public String getDescription() {
    return description;
  }

  @Override
  public String getCode() {
    return code;
  }

  @Override
  public MetricsSnapshotType getType() {
    return type;
  }

  @Override
  public boolean equals( Object obj ) {
    if ( !( obj instanceof MetricsInterface ) ) {
      return false;
    }
    if ( this == obj ) {
      return true;
    }

    return ( (MetricsInterface) obj ).getCode().equalsIgnoreCase( code );
  }

  public static List<MetricsInterface> getDefaultMetrics() {
    List<MetricsInterface> metrics = new ArrayList<MetricsInterface>();

    for ( Field field : Metrics.class.getDeclaredFields() ) {
      if ( field.getType().equals( Metrics.class ) && field.getName().startsWith( "METRIC_" ) ) {
        field.setAccessible( true );
        try {
          metrics.add( (MetricsInterface) field.get( null ) );
        } catch ( Exception e ) {
          e.printStackTrace(); // it either works or doesn't, seems more like a JRE problem if it doesn't.
        }
      }
    }

    return metrics;
  }
}
